﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows.Forms;
using McTools.Xrm.Connection;
using Microsoft.Xrm.Sdk.Messages;
using Microsoft.Xrm.Sdk.Metadata;
using Tanguy.WinForm.Utilities.DelegatesHelpers;

namespace SiteMapEditor.Forms.Entities
{
    public partial class EntityPicker : Form
    {
        #region Variables

        /// <summary>
        /// Manager to connect to a CRM server
        /// </summary>
        private ConnectionManager cManager;

        #endregion Variables

        #region Constructor

        /// <summary>
        /// Initializes a new instance of class EntityPicker
        /// </summary>
        public EntityPicker()
        {
            InitializeComponent();

            if (MainForm.service == null)
            {
                this.cManager = new ConnectionManager(this);
                this.cManager.ConnectionSucceed += new ConnectionManager.ConnectionSucceedEventHandler(cManager_ConnectionSucceed);
                this.cManager.ConnectionFailed += new ConnectionManager.ConnectionFailedEventHandler(cManager_ConnectionFailed);
                this.cManager.AskForConnection(null);
            }
            else
            {
                this.FillEntities();
            }
        }

        #endregion Constructor

        #region Properties

        /// <summary>
        /// Gets or Sets the selected entity
        /// </summary>
        public string SelectedEntity { get; set; }

        #endregion Properties

        #region Connection Manager events

        void cManager_ConnectionFailed(object sender, ConnectionFailedEventArgs e)
        {
            CommonDelegates.DisplayMessageBox(this, "Connection error: " + e.FailureReason, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            ListViewDelegates.SetEnableState(this.lvSelectedEntities, false);
        }

        void cManager_ConnectionSucceed(object sender, ConnectionSucceedEventArgs e)
        {
            MainForm.service = e.OrganizationService;

            // Disables controls while loading entities
            ListViewDelegates.SetEnableState(this.lvSelectedEntities, false);
            CommonDelegates.SetEnableState(this.btnCancel, false);
            CommonDelegates.SetEnableState(this.btnValidate, false); 
            
            // Run work
            BackgroundWorker worker = new BackgroundWorker();
            worker.DoWork += new DoWorkEventHandler(worker_DoWork);
            worker.RunWorkerAsync();
        }

        void worker_DoWork(object sender, DoWorkEventArgs e)
        {
            this.FillEntities();
        }

        #endregion Connection Manager events

        #region Methods

        /// <summary>
        /// Fills the list of entities
        /// </summary>
        private void FillEntities()
        {
            // Checks the application cache and load it if needed
            if (MainForm.entityCache == null || MainForm.entityCache.Count == 0)
            {
                MainForm.entityCache = new List<EntityMetadata>();

                RetrieveAllEntitiesRequest request = new RetrieveAllEntitiesRequest()
                {
                    EntityFilters = EntityFilters.Entity
                };

                RetrieveAllEntitiesResponse response = (RetrieveAllEntitiesResponse)MainForm.service.Execute(request);

                foreach (EntityMetadata emd in response.EntityMetadata)
                {
                    MainForm.entityCache.Add(emd);
                }
            }

            // Displays entities
            foreach (EntityMetadata emd in MainForm.entityCache)
            {
                if (emd.IsCustomizable.Value && emd.DisplayName.UserLocalizedLabel != null)
                {
                    ListViewItem item = new ListViewItem()
                    {
                        Text = emd.DisplayName.UserLocalizedLabel.Label,
                        Tag = emd
                    };

                    ListViewDelegates.AddItem(this.lvSelectedEntities, item);
                }
            }

            // Enables controls
            ListViewDelegates.Sort(this.lvSelectedEntities);
            ListViewDelegates.SetEnableState(this.lvSelectedEntities, true);
            CommonDelegates.SetEnableState(this.btnCancel, true);
            CommonDelegates.SetEnableState(this.btnValidate, true);
        }

        private void btnValidate_Click(object sender, EventArgs e)
        {
            if (this.lvSelectedEntities.SelectedItems.Count == 0)
            {
                MessageBox.Show(this, "Please select at least one entity!", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
            else
            {
                this.SelectedEntity = ((EntityMetadata)this.lvSelectedEntities.SelectedItems[0].Tag).LogicalName;
                this.DialogResult = DialogResult.OK;
                this.Close();
            }
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            this.SelectedEntity = string.Empty;
            this.DialogResult = DialogResult.Cancel;
            this.Close();
        }

        #endregion Methods
    }
}
